package com.lzt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzt.constants.SystemCanstants;
import com.lzt.domain.ResponseResult;
import com.lzt.domain.entity.Article;
import com.lzt.domain.entity.Category;
import com.lzt.service.ArticleService;
import com.lzt.mapper.ArticleMapper;
import com.lzt.service.CategoryService;
import com.lzt.utils.BeanCopyUtils;
import com.lzt.vo.ArticleDetailVo;
import com.lzt.vo.ArticleListVo;
import com.lzt.vo.HotArticleVO;
import com.lzt.vo.PageVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

import static com.lzt.constants.SystemCanstants.*;

/**
* @author Administrator
* @description 针对表【sg_article(文章表)】的数据库操作Service实现
* @createDate 2024-11-19 20:43:27
*/

    @Service
//ServiceImpl是mybatisPlus官方提供的
    public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
        @Override
        public ResponseResult hotArticleList() {

            //查询热门文章，封装成ResponseResult返回。把所有查询条件写在queryWrapper里面
            LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
            //查询的不能是草稿。也就是Status字段不能是0
            queryWrapper.eq(Article::getStatus,ARTICLE_STATUS_NORMAL);
            //按照浏览量进行排序。也就是根据ViewCount字段降序排序
            queryWrapper.orderByDesc(Article::getViewCount);
            //最多只能查询出来10条消息。当前显示第一页的数据，每页显示10条数据
            Page<Article> page = new Page<>(ARTICLE_STATUS_CURRENT,ARTICLE_STATUS_SIZE);
            page(page,queryWrapper);
            //获取最终的查询结果
            List<Article> articles = page.getRecords();
            List<HotArticleVO> articleVos = BeanCopyUtils.copyBeanList(articles, HotArticleVO.class);
            return ResponseResult.okResult(articleVos);
        }
    @Autowired
    //注入我们写的CategoryService接口
    private CategoryService categoryService;
    @Override
    public ResponseResult articleList(Integer pageNum, Integer pageSize, Long categoryId) {
        LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        //判空。如果前端传了categoryId这个参数，那么查询时要和传入的相同。第二个参数是数据表的文章id，第三个字段是前端传来的文章id
        lambdaQueryWrapper.eq(Objects.nonNull(categoryId)&&categoryId>0,Article::getCategoryId,categoryId);

        //只查询状态是正式发布的文章。Article实体类的status字段跟0作比较，一样就表示是正式发布的
        lambdaQueryWrapper.eq(Article::getStatus,SystemCanstants.ARTICLE_STATUS_NORMAL);

        //对isTop字段进行降序排序，实现置顶的文章(isTop值为1)在最前面
        lambdaQueryWrapper.orderByDesc(Article::getIsTop);

        //分页查询
        Page<Article> page = new Page<>(pageNum,pageSize);
        page(page,lambdaQueryWrapper);

        /**
         * 解决categoryName字段没有返回值的问题。在分页之后，封装成ArticleListVo之前，进行处理
         */
        //用categoryId来查询categoryName(category表的name字段)，也就是查询'分类名称'。有两种方式来实现，如下
        List<Article> articles = page.getRecords();
        //第一种方式，用for循环遍历的方式
        for (Article article : articles) {
            //'article.getCategoryId()'表示从article表获取category_id字段，然后作为查询category表的name字段
            Category category = categoryService.getById(article.getCategoryId());
            //把查询出来的category表的name字段值，也就是article，设置给Article实体类的categoryName成员变量
            article.setCategoryName(category.getName());

        }

        //第二种方式，用stream流的方式


        //把最后的查询结果封装成ArticleListVo(我们写的实体类)。BeanCopyUtils是我们写的工具类
        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), ArticleListVo.class);

        //把上面那行的查询结果和文章总数封装在PageVo(我们写的实体类)
        PageVo pageVo = new PageVo(articleListVos,page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getArticleDetail(Long id) {
        //根据id查询文章
        Article article = getById(id);

        //把最后的查询结果封装成ArticleListVo(我们写的实体类)。BeanCopyUtils是我们写的工具类
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);

        //根据分类id，来查询分类名
        Long categoryId = articleDetailVo.getCategoryId();
        Category category = categoryService.getById(categoryId);
        //如果根据分类id查询的到分类名，那么就把查询到的值设置给ArticleDetailVo实体类的categoryName字段
        if(category!=null){
            articleDetailVo.setCategoryName(category.getName());
        }

        //封装响应返回。ResponseResult是我们在huanf-framework工程的domain目录写的实体类
        return ResponseResult.okResult(articleDetailVo);
    }
}





